#if !DISABLE_HYBRIDCLR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using Newtonsoft.Json;
using System.IO;
using HybridCLR;
using HybridCLR.Editor;
using HybridCLR.Editor.Commands;
using System.Linq;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using UnityEditorInternal;
using cframework;

public static class HotUpdateCodeTool
{
    public static List<string> AOTMetaAssemblyNames { get; } = new List<string>()
    {
        "mscorlib",
        "System",
        "System.Core",
    };

    static string dllResourcesOutputPath = $"Assets/HyBridCLR_Cache/{HotUpdateDllMgr.hotupdate_code_dir}";

//#if UNITY_IOS
//    [MenuItem("cframework/HotUpdateCodeTool/CopyEditorCoreModuleDll")]
//    public static void CopyEditorCoreModuleDll()
//    {
//		string editorCoreModuleDllPath = System.IO.Path.Combine(EditorApplication.applicationPath, "Contents/Managed/UnityEngine/UnityEditor.CoreModule.dll");
//		string editorCoreModuleDllBackupPath = editorCoreModuleDllPath + "_backup_" + MD5Hash.GetMD5HashFromFile(editorCoreModuleDllPath);

//		if(!CommonUtil.Exists(editorCoreModuleDllBackupPath))
//		{
//			Debug.LogError("copyed  " + editorCoreModuleDllPath);
//			CommonUtil.Copy(editorCoreModuleDllPath, editorCoreModuleDllBackupPath);
//		}
		
//		string unityVersion = Application.unityVersion;
//        for(int i = 0; i < unityVersion.Length; i++)
//        {
//            if(unityVersion[i] >= 'a' && unityVersion[i] <= 'z')
//            {
//                unityVersion = unityVersion.Substring(0, i);
//                break;
//            }
//        }

//        string srcDllPath = Application.dataPath  + "/cframework/third_party/HybridCLR/ModifiedUnityAssemblies/" + unityVersion + "/UnityEditor.CoreModule-Mac.dll.bytes";
//        if(!CommonUtil.Exists(srcDllPath))
//        {
//            string projectPath = System.IO.Path.GetDirectoryName(Application.dataPath);
//            string packageCachePath = System.IO.Path.Combine(projectPath, "Library/PackageCache");
//            string hybridclrPath = System.IO.Directory.GetDirectories(packageCachePath, "com.focus-creative-games.hybridclr_unity*", SearchOption.TopDirectoryOnly)[0];
//            srcDllPath = System.IO.Path.Combine(hybridclrPath, "Data/ModifiedUnityAssemblies/" + unityVersion + "/UnityEditor.CoreModule-Mac.dll.bytes");
//        }
//		CommonUtil.Copy(srcDllPath, editorCoreModuleDllPath);
//    }
//#endif

    public static string ToRelativeAssetPath(string s)
    {
        return s.Substring(s.IndexOf("Assets/"));
    }

    public static bool CheckHotUpdateCodeDependencedAsset()
    {
        bool dependenced = false;

        var hotUpdateDllNames = SettingsUtil.HotUpdateAssemblyFilesIncludePreserved;

        var scenes = EditorBuildSettings.scenes;
        foreach(var scene in scenes)
        {
            if(!scene.enabled)
            {
                continue;
            }

            // foreach (var dll in )
            // {
            //     string dllPath = $"{hotupdateDllSrcDir}/{dll}";
            //     string dllBytesPath = $"{tempDir}/{dll}.bytes";
            //     File.Copy(dllPath, dllBytesPath, true);
            //     notSceneAssets.Add(dllBytesPath);
            //     Debug.Log($"[BuildAssetBundles] copy hotupdate dll {dllPath} -> {dllBytesPath}");
            // }

            

            string[] dps = AssetDatabase.GetDependencies(scene.path, true);
            foreach(var dp in dps)
            {
                if(dp.EndsWith(".cs"))
                {
                    var monoScript = AssetDatabase.LoadAssetAtPath<MonoScript>(dp);
                    System.Type t = monoScript.GetClass();
                    if (t == null) continue;

                    try
                    {
                        string dllName = t.Assembly.GetName().Name + ".dll";
                        
                        if(hotUpdateDllNames.Contains(dllName))
                        {
                            Debug.LogError("script(" + dp + ") dependenced from scene: " + scene.path);
                            dependenced = true;
                        }
                    }
                    catch(System.Exception e)
                    {
                        Debug.LogException(e);
                        Debug.LogError("failed: monoscript: " + dp);
                        throw e;
                    }
                }
            }
        }

        {
            string[] filePaths = System.IO.Directory.GetDirectories("Assets", "Resources", SearchOption.AllDirectories);

            string[] resGuids = AssetDatabase.FindAssets("*", filePaths);
            for(int i = 0; i < resGuids.Length; i++)
            {
                resGuids[i] = AssetDatabase.GUIDToAssetPath(resGuids[i]);
            }

            foreach(var r in resGuids)
            {
                string[] dps = AssetDatabase.GetDependencies(r, true);

                foreach(var dp in dps)
                {
                    if(dp.EndsWith(".cs"))
                    {
                        var monoScript = AssetDatabase.LoadAssetAtPath<MonoScript>(dp);
                        System.Type t = monoScript.GetClass();
                        string dllName = t.Assembly.GetName().Name + ".dll";
                        
                        if(hotUpdateDllNames.Contains(dllName))
                        {
                            Debug.LogError("script(" + dp + ") dependenced from asset: " + r);
                            dependenced = true;
                        }
                    }
                }
            }
        }

        return dependenced;
    }



    public static void BuildHotUpdateDll(string outputPath, int minAppVersion, string monodisPath)
    {
        string appVersionPath = outputPath + "/app_version.txt";
        string latest_il2cppinfo_dll_dir = outputPath + "/" + "il2cpp_info";
        string latest_hotupdate_dll_dir = outputPath + "/" + HotUpdateDllMgr.hotupdate_code_dir;
        string latest_inapp_dll_dir = outputPath + "/" + "latest_inapp_dll";


        CommonUtil.CreateDir(dllResourcesOutputPath);
        CopyInAppDll(latest_il2cppinfo_dll_dir, latest_inapp_dll_dir, appVersionPath, minAppVersion);
        BuildHotUpdateDll(dllResourcesOutputPath, latest_il2cppinfo_dll_dir, latest_hotupdate_dll_dir, appVersionPath, minAppVersion);
    }
    
    private static void BuildHotUpdateDll(string outputPath, string inAppDllDir, string latest_hotupdate_dll_dir, string appVersionPath, int minAppVersion)
    {
        if(CheckHotUpdateCodeDependencedAsset())
        {
            throw new System.Exception("scene used hotupdate script");
        }
        
        BuildTarget target = EditorUserBuildSettings.activeBuildTarget;

        Directory.CreateDirectory(outputPath);

        CompileDllCommand.CompileDll(target);


        List<string> notSceneAssets = new List<string>();

        var hotUpdateDllNames = SettingsUtil.HotUpdateAssemblyFilesIncludePreserved;

        string hotupdateDllSrcDir = SettingsUtil.GetHotUpdateDllsOutputDirByTarget(target);
        foreach (var dll in hotUpdateDllNames)
        {
            string dllPath = $"{hotupdateDllSrcDir}/{dll}";
            string dllBytesPath = $"{outputPath}/{dll}.bytes";
            File.Copy(dllPath, dllBytesPath, true);
        }
        

        string aotDllDir = SettingsUtil.GetAssembliesPostIl2CppStripDir(target);
        // HotUpdateAssemblyManifest manifest = HotUpdateManifest;
        // if (manifest == null)
        // {
        //     throw new System.Exception($"resource asset:{nameof(HotUpdateAssemblyManifest)} 配置不存在，请在Resources目录下创建");
        // }
        List<string> AOTMetaAssemblies= AOTMetaAssemblyNames.ToList();
        
        for(int i = 0; i < AOTMetaAssemblies.Count; i++)
        {
            AOTMetaAssemblies[i] += ".dll";
        }

        var a = SettingsUtil.HybridCLRSettings.patchAOTAssemblies;
        for(int i = 0; i < a.Length; i++)
        {
            AOTMetaAssemblies.Add(a[i]);
        }
        

        for (int i = AOTMetaAssemblies.Count - 1; i >= 0; i--)
        {
            var dll = AOTMetaAssemblies[i];
            
            string dllPath = $"{aotDllDir}/{dll}";
            if (!File.Exists(dllPath))
            {
                Debug.LogError($"ab中添加AOT补充元数据dll:{dllPath} 时发生错误,文件不存在。裁剪后的AOT dll在BuildPlayer时才能生成，因此需要你先构建一次游戏App后再打包。");

                AOTMetaAssemblies.RemoveAt(i);
                continue;
            }
            string dllBytesPath = $"{outputPath}/{dll}.bytes";
            File.Copy(dllPath, dllBytesPath, true);
        }


        


        string[] srcFilePaths = System.IO.Directory.GetFiles(dllResourcesOutputPath, "*", SearchOption.AllDirectories);
        HashSet<string> srcHashMap = new HashSet<string>();
        foreach(var p in srcFilePaths)
        {
            if(p.EndsWith(".dll.bytes"))
            {
                srcHashMap.Add(System.IO.Path.GetFileName(p));
            }
        }

        HashSet<string> destHashMap = new HashSet<string>();
        if(CommonUtil.Exists(latest_hotupdate_dll_dir))
        {
            string[] destFilePaths = System.IO.Directory.GetFiles(latest_hotupdate_dll_dir, "*", SearchOption.AllDirectories);
        
            foreach(var p in destFilePaths)
            {
                if(p.EndsWith(".dll.bytes"))
                {
                    destHashMap.Add(System.IO.Path.GetFileName(p));
                }
            }
        }

        
        bool allSame = srcHashMap.Count == destHashMap.Count;
        if(allSame)
        {
            foreach(var entry in srcHashMap)
            {
                if(!destHashMap.Contains(entry))
                {
                    allSame = false;
                    break;
                }
            }
        }



        
        int totalSize = 0;
        SortedDictionary<string, byte[]> datas = new SortedDictionary<string, byte[]>();
        foreach (var dll in hotUpdateDllNames)
        {
            string dllPath = $"{hotupdateDllSrcDir}/{dll}";
            byte[] data = CommonUtil.fileToBytes(dllPath);
            datas.Add(dll, data);

            totalSize += data.Length;
        }
        
        int offset = 0;
        byte[] newDatas = new byte[totalSize];
        foreach(var entry in datas)
        {
            System.Array.Copy(entry.Value, 0, newDatas, offset, entry.Value.Length);
            offset += entry.Value.Length;
        }

        string md5 = MD5Hash.GetMD5Hash(newDatas);


        
        string appVersionFilePath = appVersionPath;
        
        string minAppVersionStr = CommonUtil.fileToString(appVersionFilePath);

        Debug.Log("test allsame 1: " + allSame + " | " + minAppVersionStr + " | " + string.IsNullOrEmpty(minAppVersionStr) + " | " + CommonUtil.Exists(appVersionFilePath) + " | " + minAppVersion);

        if(minAppVersion == 0)
        {
            if(string.IsNullOrEmpty(minAppVersionStr))
            {
                minAppVersion = AppManager.GetAppInfo().hotupdate_version;
            }
            else
            {
                if(allSame)
                {
                    minAppVersion = int.Parse(minAppVersionStr);
                }
                else
                {
                    minAppVersion = AppManager.GetAppInfo().hotupdate_version;
                    CommonUtil.stringToFile(appVersionFilePath, minAppVersion.ToString());
                }
            }
        }
        else if(minAppVersion < 0)
		{
			minAppVersion = AppManager.GetAppInfo().hotupdate_version;
		}

        HotUpdateCodeInfo info = new HotUpdateCodeInfo();
        info.hotupdate_version = AppManager.GetAppInfo().hotupdate_version;
        info.min_app_hotupdate_version = minAppVersion;
        info.md5 = md5;
        info.build_time = System.DateTime.Now.ToString("u");
        info.build_timestamp = CommonUtil.GetTimeStamp();

        info.hotupdateDllNames = hotUpdateDllNames.ToArray();
        info.aotMetaDllNames = AOTMetaAssemblies.ToArray();

      
        string configStr = JsonConvert.SerializeObject(info, Formatting.Indented);
        CommonUtil.stringToFile(outputPath + "/" + HotUpdateDllMgr.config_file_name, configStr);

        AssetDatabase.Refresh();
    }

    public static void BuildHotUpdateBundle(string hotupdateResConfigPath, string outputPath, string last_build_dll_path, string monodisPath)
    {
        BuildHotUpdateDllBundle(hotupdateResConfigPath, outputPath, last_build_dll_path, HotUpdateDllMgr.bundle_name);
    }

    public static void BuildHotUpdateDllBundle(string hotupdateResConfigPath, string outputPath, string lastBuildDllPath, string bundleName)
    {
        string[] srcFilePaths = System.IO.Directory.GetFiles(dllResourcesOutputPath, "*", SearchOption.AllDirectories);

        //dll的md5比较逻辑，因mac和win平台的运行结果不一致，取消了
        // Dictionary<string, string> srcHashMap = new Dictionary<string, string>();
        // foreach(var p in srcFilePaths)
        // {
        //     if(p.EndsWith(".dll.bytes"))
        //     {
        //         srcHashMap.Add(System.IO.Path.GetFileName(p), GetDllFileHash(p));

        //         // Debug.LogError("test src Hash: " + System.IO.Path.GetFileName(p) + " | " + GetDllFileHash(p));
        //     }
        // }

        // Dictionary<string, string> destHashMap = new Dictionary<string, string>();
        // if(CommonUtil.Exists(lastBuildDllPath))
        // {
        //     string[] destFilePaths = System.IO.Directory.GetFiles(lastBuildDllPath, "*", SearchOption.AllDirectories);

        //     foreach(var p in destFilePaths)
        //     {
        //         if(p.EndsWith(".dll.bytes"))
        //         {
        //             destHashMap.Add(System.IO.Path.GetFileName(p), GetDllFileHash(p));

        //             // Debug.LogError("test dest Hash: " + System.IO.Path.GetFileName(p) + " | " + GetDllFileHash(p));
        //         }
        //     }
        // }

        // bool allSame = srcHashMap.Count == destHashMap.Count;
        // if(allSame)
        // {
        //     foreach(var entry in srcHashMap)
        //     {
        //         string hash = null;
        //         if(destHashMap.TryGetValue(entry.Key, out hash))
        //         {
        //             if(hash != entry.Value)
        //             {
        //                 allSame = false;
        //                 break;
        //             }
        //         }
        //         else
        //         {
        //             allSame = false;
        //             break;
        //         }
        //     }
        // }

        // if(allSame)
        // {
        //     Debug.Log("exit because all same");
        //     return;
        // }



        CommonUtil.Delete(outputPath);
        CommonUtil.CreateDir(outputPath);

        List<string> resPaths = new List<string>();
        

        foreach(var filePath in srcFilePaths)
        {
            if(filePath.EndsWith(".meta"))
            {
                continue;
            }

            var a = filePath.Replace("\\", "/");

            a = ToRelativeAssetPath(a);

            resPaths.Add(a);
        }

        var ss = AssetDatabase.LoadAssetAtPath<TextAsset>(hotupdateResConfigPath);
        var rr = Newtonsoft.Json.JsonConvert.DeserializeObject<string[]>(ss.text);

        string dir = System.IO.Path.GetDirectoryName(hotupdateResConfigPath);

        foreach (var e in rr)
        {
            var d = System.IO.Path.GetRelativePath(System.IO.Path.GetDirectoryName(Application.dataPath), System.IO.Path.GetFullPath(dir + "/" + e));

            if (System.IO.Directory.Exists(d))
            {
                string[] guids = AssetDatabase.FindAssets("*", new string[] { d });

                foreach (var g in guids)
                {
                    string p = AssetDatabase.GUIDToAssetPath(g);

                    if (p.EndsWith(".cs"))
                    {
                        continue;
                    }


                    resPaths.Add(p);
                }
            }
            else if (System.IO.File.Exists(d))
            {
                resPaths.Add(d);
            }
        }

        List<AssetBundleBuild> abs = new List<AssetBundleBuild>();
        AssetBundleBuild notSceneAb = new AssetBundleBuild
        {
            assetBundleName = bundleName,
            assetNames = resPaths.ToArray(),
        };
        abs.Add(notSceneAb);

        AssetBundleManifest manifest = BuildPipeline.BuildAssetBundles(outputPath, abs.ToArray(), BuildAssetBundleOptions.None, EditorUserBuildSettings.activeBuildTarget);
        if(manifest == null)
        {
            throw new System.Exception("BuildPipeline.BuildAssetBundles failed");
        }
        
        CommonUtil.Copy(dllResourcesOutputPath + $"/{HotUpdateDllMgr.config_file_name}", outputPath + $"/{HotUpdateDllMgr.config_file_name}");




        if(!string.IsNullOrEmpty(lastBuildDllPath))
        {
            CommonUtil.Delete(lastBuildDllPath);
            CommonUtil.CreateDir(lastBuildDllPath);


            foreach(var filePath in srcFilePaths)
            {
                if(filePath.EndsWith(".meta"))
                {
                    continue;
                }

                CommonUtil.Copy(filePath, lastBuildDllPath + "/" + System.IO.Path.GetFileName(filePath));
            }
        }
    }

    public static void CopyHotUpdateDllBundleToPlayer(string bundle_path, string outputPath)
    {
        switch(EditorUserBuildSettings.activeBuildTarget)
        {
            case BuildTarget.StandaloneWindows:
            case BuildTarget.StandaloneWindows64:
            {
                var c = System.IO.Directory.GetFiles(outputPath, "ScriptingAssemblies.json", SearchOption.AllDirectories);
                
                string b = outputPath;
                if(c.Length > 0)
                {
                    string a = c[0];
                    b = System.IO.Path.GetDirectoryName(a);
                }
            
                b = b.Replace("\\", "/");

                b += $"/StreamingAssets/{HotUpdateDllMgr.hotupdate_code_dir}";

                Debug.Log("test streaming asset path: " + b);

                CommonUtil.CopyDirectory(bundle_path, b);
            }
            break;
            case BuildTarget.StandaloneOSX:
                {
                    outputPath += ".app";

                    var c = System.IO.Directory.GetFiles(outputPath, "ScriptingAssemblies.json", SearchOption.AllDirectories);

                    string b = outputPath;
                    if (c.Length > 0)
                    {
                        string a = c[0];
                        b = System.IO.Path.GetDirectoryName(a);
                    }

                    b = b.Replace("\\", "/");

                    b += $"/StreamingAssets/{HotUpdateDllMgr.hotupdate_code_dir}";

                    Debug.Log("test streaming asset path: " + b);

                    CommonUtil.CopyDirectory(bundle_path, b);
                }
                break;
            case BuildTarget.Android:
            {
                var c = System.IO.Directory.GetFiles(outputPath, "ScriptingAssemblies.json", SearchOption.AllDirectories);
                
                string b = outputPath;
                if(c.Length > 0)
                {
                    string a = c[0];
                    b = System.IO.Path.GetDirectoryName(a);
                    b = System.IO.Path.GetDirectoryName(b);
                    b = System.IO.Path.GetDirectoryName(b);
                }
            
                b = b.Replace("\\", "/");

                b += $"/{HotUpdateDllMgr.hotupdate_code_dir}";

                Debug.Log("test streaming asset path: " + b);

                CommonUtil.CopyDirectory(bundle_path, b);
            }
            break;
            case BuildTarget.iOS:
            {
                var c = System.IO.Directory.GetFiles(outputPath, "ScriptingAssemblies.json", SearchOption.AllDirectories);
                
                string b = outputPath;
                if(c.Length > 0)
                {
                    string a = c[0];
                    b = System.IO.Path.GetDirectoryName(a);
                    b += "/Raw";
                }
            
                b = b.Replace("\\", "/");

                b += $"/{HotUpdateDllMgr.hotupdate_code_dir}";

                Debug.Log("test streaming asset path: " + b);

                CommonUtil.CopyDirectory(bundle_path, b);
            }
            break;
        }


    }

    public static string AddNamespaceToCode(string codeStr, string newNamespace)
    {
        return "namespace " + newNamespace + " {\n" + codeStr + "\n}";
    }

    [MenuItem("cframework/HotUpdateCodeTool/CopyCommonCode")]
    public static void CopyCommonCode()
    {
        string srcPath = "Assets/cframework";
        if (!System.IO.Directory.Exists(srcPath)) return;

        CopyCommonCode(srcPath + "/cframework_hotupdate", "hotupdate");
        CopyCommonCode(srcPath + "/cframework_launch", "launch");
    }

    public static void CopyCommonCode(string destPath, string newNameSpace)
    {
        string srcPath = "Assets/cframework";
        if (!System.IO.Directory.Exists(srcPath)) return;

        {
            string[] scriptFileGuids2 = AssetDatabase.FindAssets("t:script", new string[]{destPath});
            foreach(var s in scriptFileGuids2)
            {
                var p = AssetDatabase.GUIDToAssetPath(s);
                System.IO.File.Delete(p);
            }
        }

        

        HashSet<string> asmDefPaths = new HashSet<string>();
        {
            string[] asmFilePaths = AssetDatabase.FindAssets("t:asmdef", new string[]{"Assets"});
            if(asmFilePaths.Length > 0)
            {
                foreach(var b in asmFilePaths)
                {
                    var c = AssetDatabase.GUIDToAssetPath(b);

                    var d = System.IO.Path.GetDirectoryName(c);
                    d = d.Replace("\\", "/");

                    if(d == srcPath)
                    {
                        continue;
                    }
                    

                    asmDefPaths.Add(d + "/");
                }
            }
        }

        Dictionary<string, string> pathToPathMap = new Dictionary<string, string>();

        string[] scriptFileGuids = AssetDatabase.FindAssets("t:script", new string[]{srcPath});
        for(int i = 0; i < scriptFileGuids.Length; i++)
        {
            string scriptFileGuid = scriptFileGuids[i];
            string scriptPath = AssetDatabase.GUIDToAssetPath(scriptFileGuid);
            
            if(scriptPath.Contains("/Editor/"))
            {
                continue;
            }


            bool found = false;
            foreach(var d in asmDefPaths)
            {
                if(scriptPath.StartsWith(d))
                {
                    found = true;
                    break;
                }
            }

            if(found)
            {
                continue;
            }
            
            string destPath2 = destPath + scriptPath.Substring(srcPath.Length);

            pathToPathMap.Add(scriptPath, destPath2);
        }




        foreach(var entry in pathToPathMap)
        {
            string dirName = System.IO.Path.GetDirectoryName(entry.Value);
            CommonUtil.CreateDir(dirName);
        }

        AssetDatabase.Refresh();

        foreach(var entry in pathToPathMap)
        {
            string codeStr = CommonUtil.fileToString(entry.Key);
            string newCodeStr = AddNamespaceToCode(codeStr, newNameSpace);
            CommonUtil.stringToFile(entry.Value, newCodeStr);
        }

        AssetDatabase.Refresh();
    }


    public static void CopyInAppDll(string outputPath, string inAppDllOutoutPath, string appVersionPath, int minAppVersion)
    {
        string srcPath = SettingsUtil.GetAssembliesPostIl2CppStripDir(EditorUserBuildSettings.activeBuildTarget);



        string lastInappDllDir = inAppDllOutoutPath;
        CommonUtil.CreateDir(lastInappDllDir);

        {
            string[] oldDllFilePaths = System.IO.Directory.GetFiles(lastInappDllDir, "*", SearchOption.AllDirectories);
            foreach (var filePath in oldDllFilePaths)
            {
                CommonUtil.Delete(filePath);
            }

            string[] srcDllFilePaths = System.IO.Directory.GetFiles(srcPath, "*.dll", SearchOption.AllDirectories);
            foreach (var filePath in srcDllFilePaths)
            {
                string fileName = System.IO.Path.GetFileName(filePath);

                string destPath = lastInappDllDir + "/" + fileName;
                CommonUtil.Copy(filePath, destPath);
            }
        }




        bool allSame = true;

        string il2cppInfoDirPath = outputPath;



        
        

        CommonUtil.CreateDir(il2cppInfoDirPath);


        HashSet<string> srcMethodBridgeFileNames = new HashSet<string>();
        HashSet<string> destMethodBridgeFileNames = new HashSet<string>();
      

        Dictionary<string, string> needCompareFileMap = new Dictionary<string, string>();

        {
            string srcLinkFilePath = $"{Application.dataPath}/{SettingsUtil.HybridCLRSettings.outputLinkFile}" ;;
            string destLinkFilePath = il2cppInfoDirPath + "/" + System.IO.Path.GetFileName(srcLinkFilePath);
            destLinkFilePath = destLinkFilePath.Replace('\\', '/');
            needCompareFileMap.Add(srcLinkFilePath, destLinkFilePath);
        }

        if(allSame)
        {
            foreach(var entry in needCompareFileMap)
            {
                var hash0 = MD5Hash.GetMD5HashFromFile(entry.Key);
                if(!CommonUtil.Exists(entry.Value))
                {
                    allSame = false;
                    break;
                }
                
                var hash1 = MD5Hash.GetMD5HashFromFile(entry.Value);
                if(hash0 != hash1)
                {
                    allSame = false;
                    break;
                }
            }
        }

        {
            string[] oldFilePaths = System.IO.Directory.GetFiles(il2cppInfoDirPath, "*", SearchOption.AllDirectories);
            foreach(var filePath in oldFilePaths)
            {
                CommonUtil.Delete(filePath);
            }

            foreach(var entry in needCompareFileMap)
            {
                CommonUtil.Copy(entry.Key, entry.Value);
            }
        }


        string versionFilePath = appVersionPath;
        if(!allSame || !CommonUtil.Exists(versionFilePath) || minAppVersion != 0)
        {
            if(minAppVersion <= 0)
            {
                minAppVersion = AppManager.GetAppInfo().hotupdate_version;
            }

            CommonUtil.stringToFile(versionFilePath, minAppVersion.ToString());
        }
    }
}

#endif